package com.example.skillcinema.ui.screens.main

import android.content.Intent
import android.content.res.Resources
import android.content.res.TypedArray
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.bumptech.glide.Glide
import com.example.skillcinema.R
import com.example.skillcinema.adapters.FilmRecyclerViewAdapter
import com.example.skillcinema.adapters.GalleryForPreviewRecyclerViewAdapter
import com.example.skillcinema.adapters.StaffForPreviewRecyclerViewAdapter
import com.example.skillcinema.databinding.FragmentCollectionDialogBinding
import com.example.skillcinema.databinding.FragmentFilmDetailsBinding
import com.example.skillcinema.db.enums.FilmFetchType
import com.example.skillcinema.db.localdb.tables.HistoryEntity
import com.example.skillcinema.db.repositories.BaseRepository.Companion.PREVIEW_ITEMS_COUNT
import com.example.skillcinema.extensions.sliceForPreview
import com.example.skillcinema.ui.screens.main.FilmAllFragment.Companion.FILM_FETCH_TYPE_ARG
import com.example.skillcinema.ui.screens.main.viewmodels.FilmDetailViewModel
import com.example.skillcinema.utils.sharemodels.FilmDataToShare
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch


@AndroidEntryPoint
class FilmDetailsFragment : Fragment() {
    private var filmId: Int? = null
    private var _binding: FragmentFilmDetailsBinding? = null
    private val binding: FragmentFilmDetailsBinding
        get() = _binding!!
    private val viewModel: FilmDetailViewModel by viewModels<FilmDetailViewModel>()
    private var filmName: String = ""
    private var filmUrl: String = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            filmId = it.getInt(FILM_ID_ARG)
            viewModel.id = filmId!!
            viewModel.loadIt()
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentFilmDetailsBinding.inflate(inflater, container, false)
        return binding.root
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        (activity as? AppCompatActivity)?.setSupportActionBar(binding.toolbar)
        (activity as? AppCompatActivity)?.supportActionBar?.setDisplayHomeAsUpEnabled(true)
        (activity as? AppCompatActivity)?.supportActionBar?.setDisplayShowTitleEnabled(false)
        binding.toolbar.title = ""
        binding.toolbar.setNavigationOnClickListener {
            findNavController().navigateUp()
        }
        val actorsAdapter: StaffForPreviewRecyclerViewAdapter =
            StaffForPreviewRecyclerViewAdapter { id -> staffClicked(id) }
        val staffAdapter: StaffForPreviewRecyclerViewAdapter =
            StaffForPreviewRecyclerViewAdapter { id -> staffClicked(id) }
        val galleryAdapter: GalleryForPreviewRecyclerViewAdapter =
            GalleryForPreviewRecyclerViewAdapter()
        val similarAdapter: FilmRecyclerViewAdapter =
            FilmRecyclerViewAdapter({ id -> filmDetail(id) }, { showAllCollectionFilms() })
        binding.actorsRecyclerView.adapter = actorsAdapter
        binding.staffRecyclerView.adapter = staffAdapter
        binding.galleryRecyclerView.adapter = galleryAdapter
        binding.similarRecyclerView.adapter = similarAdapter

        binding.showAllSerialSeasonsButton.setOnClickListener { showSeasonInfo(filmId!!) }
        binding.addToFavoriteImageButton.setOnClickListener {
            viewModel.toggleCollection(1)
        }
        binding.addToCollectionImageButton.setOnClickListener {
            viewModel.toggleCollection(2)
        }
        binding.addToSeenImageButton.setOnClickListener {
            viewModel.toggleCollection(3)
        }
        binding.moreActionsImageButton.setOnClickListener {
            showDialog()
        }
        binding.shareImageButton.setOnClickListener {
            if (filmUrl != "") {

                val sendIntent: Intent = Intent().apply {
                    action = Intent.ACTION_SEND
                    putExtra(Intent.EXTRA_TEXT, filmUrl)
                    type = "text/plain"
                }
                val shareIntent = Intent.createChooser(sendIntent, null)
                startActivity(shareIntent)
            } else {
                Snackbar.make(it, "No url found", Snackbar.LENGTH_LONG).show()
            }
        }

        lifecycleScope.run {
            with(binding) {
                launch {
                    viewModel.repository.db.historyDao().insertHistory(HistoryEntity(0, filmId!!))
                }
                launch {
                    viewModel.filmDataFlow.collect { film ->
                        film?.let {
                            filmName = it.nameRu.toString()
                            rateAndNameTextView.text = buildString {
                                append(it.ratingKinopoisk ?: "")
                                append(" " + it.nameRu)
                            }
                            yearAndGenreTextView.text = buildString {
                                append(it.year ?: "")
                                append(" " + it.genres.first().genre)
                            }
                            countryAndDurationTextView.text = buildString {
                                append(it.countries.first().country)
                                if (it.filmLength != null) {
                                    append(", ")
                                    append(it.filmLength)
                                    append(" min")
                                }
                            }
                            filmUrl = it.webUrl ?: ""
                            if (it.shortDescription == null) shortDescriptionTextView.visibility =
                                View.GONE
                            if (it.description == null) descriptionTextView.visibility = View.GONE
                            shortDescriptionTextView.text = it.shortDescription
                            descriptionTextView.text = it.description ?: ""
                            if (film.serial == true) {
                                seasonsLinearLayout.visibility = View.VISIBLE
                            }
                            Glide.with(filmImageView.context).load(it.posterUrl)
                                .placeholder(android.R.drawable.progress_indeterminate_horizontal)
                                .error(android.R.drawable.stat_notify_error).into(filmImageView)
                        }
                    }
                }
                launch {
                    viewModel.actorsFlow.collect {
                        if (it.count() > 0) actorsLayout.visibility = View.VISIBLE
                        if (it.count() > PREVIEW_ITEMS_COUNT) showAllActorsButton.visibility =
                            View.VISIBLE
                        showAllActorsButton.setOnClickListener {
                            showAllStaff(true)
                        }
                        showAllActorsButton.text = it.count().toString()
                        actorsAdapter.setData(it.sliceForPreview())
                    }
                }
                launch {
                    viewModel.staffFlow.collect {
                        if (it.count() > 0) staffLayout.visibility = View.VISIBLE
                        if (it.count() > PREVIEW_ITEMS_COUNT) showAllStaffButton.visibility =
                            View.VISIBLE
                        showAllStaffButton.setOnClickListener {
                            showAllStaff(false)
                        }
                        showAllStaffButton.text = it.count().toString()
                        staffAdapter.setData(it.sliceForPreview())
                    }
                }
                launch {
                    viewModel.seasonAndSeriesFlow.collect {
                        if (it.count() > PREVIEW_ITEMS_COUNT) showAllSerialSeasonsButton.visibility =
                            View.VISIBLE
                        if (it.count() > 0) seasonTextView.text = buildString {
                            append(it.last().number)
                            append(getString(R.string.season))
                            append(it.last().episodes.last().episodeNumber)
                            append(getString(R.string.series))
                        }
                    }
                }
                launch {
                    viewModel.galleryFlow.collect {
                        if (it.count() > 0) {
                            galleryLayout.visibility = View.VISIBLE
                        }
                        if (viewModel.galleryImageCount > PREVIEW_ITEMS_COUNT) {
                            showAllGalleryButton.visibility = View.VISIBLE
                        }
                        showAllGalleryButton.text = viewModel.galleryImageCount.toString()
                        showAllGalleryButton.setOnClickListener {
                            showGallery()
                        }
                        galleryAdapter.setData(it.sliceForPreview())
                    }
                }
                launch {
                    viewModel.similarFlow.collect {
                        if (it.count() > 0) similarLayout.visibility = View.VISIBLE
                        if (it.count() >= PREVIEW_ITEMS_COUNT) showAllSimilarButton.visibility =
                            View.VISIBLE
                        showAllSimilarButton.setOnClickListener {
                            showAllCollectionFilms()
                        }
                        showAllSimilarButton.text = it.count().toString()
                        similarAdapter.setData(it)
                    }
                }
                launch {
                    val ta = requireContext().theme.obtainStyledAttributes(R.styleable.ViewStyle)
                    val selectedColor = ta.getColor(R.styleable.ViewStyle_primaryColor, 0)
                    val notSelectedColor = requireContext().getColor(R.color.white)
                    viewModel.filmCollectionsFlow.collect {
                        if (it.find { collection -> collection.collectionId == 1 } != null) {
                            binding.addToFavoriteImageButton.setColorFilter(
                                selectedColor
                            )
                        } else {
                            binding.addToFavoriteImageButton.setColorFilter(
                                notSelectedColor
                            )
                        }
                        if (it.find { collection -> collection.collectionId == 2 } != null) {
                            binding.addToCollectionImageButton.setColorFilter(
                                selectedColor
                            )
                        } else {
                            binding.addToCollectionImageButton.setColorFilter(
                                notSelectedColor
                            )
                        }
                        if (it.find { collection -> collection.collectionId == 3 } != null) {
                            binding.addToSeenImageButton.setImageResource(R.drawable.ic_seen)
                            binding.addToSeenImageButton.setColorFilter(
                                selectedColor
                            )
                        } else {
                            binding.addToSeenImageButton.setImageResource(R.drawable.ic_not_seen)
                            binding.addToSeenImageButton.setColorFilter(
                                notSelectedColor
                            )
                        }
                    }
                }
            }
        }
    }

    private fun showDialog() {
        val bundle = Bundle()
        bundle.putInt(CollectionDialogFragment.Companion.FILM_ID_ARG, filmId!!)

        val dialog =
            CollectionDialogFragment()
        dialog.setArguments(bundle)
        dialog.lifecycle.addObserver(
            LifecycleEventObserver { source, event ->
                if (event == Lifecycle.Event.ON_STOP) {
                    viewModel.loadFilmCollections()
                }
            })
        dialog.show(parentFragmentManager, "dialog")
    }

    private fun showAllStaff(isActor: Boolean) {
        val bundle: Bundle = Bundle().apply {
            putInt(StaffListFragment.STAFF_ID_ARG, filmId!!)
            putBoolean(StaffListFragment.STAFF_IS_ACTOR, isActor)
        }
        findNavController().navigate(
            R.id.action_filmDetailsFragment_to_staffListFragment, bundle
        )
    }

    private fun staffClicked(id: Int) {
        val bundle: Bundle = Bundle().apply {
            putInt(StaffDetailFragment.STAFF_ID_ARG, id)
        }
        findNavController().navigate(
            R.id.action_filmDetailsFragment_to_staffDetailFragment, bundle
        )
    }

    private fun showSeasonInfo(id: Int) {
        val bundle: Bundle = Bundle().apply {
            putInt(SeasonDetailsFragment.FILM_ID_ARG, id)
            putString(SeasonDetailsFragment.FILM_NAME_ARG, filmName)
        }
        findNavController().navigate(
            R.id.action_filmDetailsFragment_to_seasonDetailsFragment, bundle
        )
    }

    private fun filmDetail(id: Int) {
        val bundle: Bundle = Bundle().apply {
            putInt(FILM_ID_ARG, id)
        }
        findNavController().navigate(R.id.action_homeFragment_to_filmDetailsFragment, bundle)
    }

    private fun showAllCollectionFilms() {
        val bundle: Bundle = Bundle().apply {
            putParcelable(
                FILM_FETCH_TYPE_ARG, FilmDataToShare(
                    filmId!!,
                    FilmFetchType.SIMILAR,
                    null,
                    getString(R.string.similar_title, filmName)
                )
            )
        }
        findNavController().navigate(R.id.action_filmDetailsFragment_to_filmAllFragment, bundle)
    }

    private fun showGallery() {
        val bundle: Bundle = Bundle().apply {
            putInt(GalleryListFragment.GALLERY_FILM_ID, filmId!!)
        }
        findNavController().navigate(R.id.action_filmDetailsFragment_to_galleryListFragment, bundle)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    companion object {

        @JvmStatic
        fun newInstance(param1: Int) = FilmDetailsFragment().apply {
            arguments = Bundle().apply {
                putInt(FILM_ID_ARG, param1)
            }
        }

        const val FILM_ID_ARG = "film_id"
    }
}